package metier;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import librairies.liste.interfaces.IListeE;
import utils.EnumUtils;
import utils.StringUtils;

import commande.Lien;

import enumeration.type.ETypeFichier;

/**
 * classe qui permet de faire des copies de fichier.
 * 
 * @author mlozach
 */
public class Transfere
{
	private int posRacinePotentielle;
	private Lien lien;
	
	public Transfere()
	{
		this.posRacinePotentielle = 0;
		this.lien = Lien.getInstance();
	}
	
	/**
	 * permet de lancer le transfere
	 * @param file le fichier a transferer
	 * @param lien le lien du dossier de sortie 
	 * @param type le type de fichier
	 * @return vrai si transfere reussi
	 */
	public boolean EnregisterFile(File file, String lien, ETypeFichier type)
	{
		if(file == null || !file.exists())
		{
			return false;
		}
		
		if(this.lien.isLien(lien))
		{
			return copy(file.getAbsolutePath(), lien + file.getName());
		}
		else
		{
			String extention = file.getName().substring(file.getName().lastIndexOf('.') + 1, file.getName().length());
			String chemain = creationChemain(extention, type);
						
			if(chemain != null)
			{
				creationChemain(chemain);
				
				return copy(file.getAbsolutePath(), chemain + file.getName());
			}
			else
			{
				return false;
			}
		}
	}
	
	/**
	 * permet de cree les dossiers si il n'existe pas
	 * @param chemain le chemain a cree
	 * @return true si le chemain est cree
	 */
	private boolean creationChemain(String chemain)
	{
		File f = new File(chemain);
		if(f.exists())
		{
			return true;
		}
		else
		{
			f.mkdirs();
			
			if(f.exists())
			{
				return true;
			}
		}
		
		return false;
	}

	/**
	 * permet de creer le chemain de sortie
	 * @param extention l'extesion du fichier
	 * @param type le type de rangement
	 * @return le chemain de sortie
	 */
	private String creationChemain(String extention, ETypeFichier type)
	{
		String racines = cleExist();
		if(racines != null)
		{
			StringBuilder racineBuil = new StringBuilder(racines);
			
			racineBuil.append(this.lien.getSlash());
			if(type != null)
			{
				racineBuil.append(type.getValue());
				racineBuil.append(this.lien.getSlash());
				return racineBuil.toString();
			}
			else if(extention != null)
			{
				racineBuil.append(EnumUtils.typeExtension(extention));
				racineBuil.append(this.lien.getSlash());
				return racineBuil.toString();
			}
			else
			{
				racineBuil.append(ETypeFichier.AUTRE);
				racineBuil.append(this.lien.getSlash());
				return racineBuil.toString();
			}
		}
		else
		{
			return null;
		}
	}
	
	/**
	 * permet de retourner le lien de la racine choisie.
	 * @return le string du systeme stockage.
	 */
	private String cleExist(){
		IListeE<String> racinePotentielle = this.lien.getRacinePotentielle();
		if(racinePotentielle.size() > this.posRacinePotentielle)
		{
			File racine = new File(racinePotentielle.get(this.posRacinePotentielle));
			if(racine.canWrite())
			{
				return racinePotentielle.get(this.posRacinePotentielle);
			}
			else
			{
				this.posRacinePotentielle = 0;
				
				while(!racine.canWrite() || this.posRacinePotentielle !=  racinePotentielle.size())
				{
					racine = new File(racinePotentielle.get(this.posRacinePotentielle));
					this.posRacinePotentielle = this.posRacinePotentielle + 1;
				}
				
				if(racine.canWrite())
				{
					this.posRacinePotentielle = this.posRacinePotentielle - 1;
					return racinePotentielle.get(this.posRacinePotentielle);
				}
				else
				{
					this.posRacinePotentielle = 0;
					return null;
				}
			}
		}
		else
		{
			return null;
		}
	}

	/**
	 * permet de faire une copie de fichier sans suppression
	 * @param original le lien du fichier originel
	 * @param copie le chemain de la creation du nouveau fichier
	 * @return return vrai si copie reussi
	 */
	private boolean copy(String original, String copie)
	{
		if(StringUtils.isEmpty(original) || StringUtils.isEmpty(copie)) return false;
		
		try
		{
			File f1 = new File(original);
			File f2 = new File(copie);
			InputStream in = new FileInputStream(f1);		  
			OutputStream out = new FileOutputStream(f2);
	
			byte[] buf = new byte[1024];
			int len;
			while ((len = in.read(buf)) > 0)
			{
				out.write(buf, 0, len);
			}
			in.close();
			out.close();
		}catch(IOException e)
		{
			e.printStackTrace();
			return false;
		}
		return true;
	}
}